/**
 * 光源类
 */

import {
  DirectionalLight,
  PointLight,
  SpotLight,
  SpotLightHelper,
} from "../3rdParty/three.js/build/three.module.js";

import A3ObjectTypes from "../A3ObjectTypes.js";
import { A3GraphicsObject } from "./Graphics.js";
 
class A3Light extends A3GraphicsObject {
  
  intensity = 0.9;
  color = 0xcccccc;
  decay = .1;
  distance = 2;

  lightHelper = undefined;

  constructor( x, y, z ) {

    super( 1, 1, 1 );

    x = isNaN(x) ? 0 : x;
    y = isNaN(x) ? 0 : y;
    z = isNaN(x) ? 0 : z;

    this.position.set( x, y, z );
    this.visual.visible = false;

  }

  update() {
    if( this.lightHelper ) this.lightHelper.update();
  }

}

// 点光源
class A3PointLight extends A3Light {

  type = A3ObjectTypes.PointLight;
  name = A3ObjectTypes.PointLight;

  constructor( x, y, z ) {

    super( x, y, z );

		const light = new PointLight( this.color, this.intensity, this.decay );
		light.castShadow = true;
		light.shadow.bias = - 0.005; // reduces self-shadowing on double-sided objects

    this.threeObject.add( light );
    this.threeObject.position.copy( this.position );

  }

}

class A3SpotLight extends A3Light {

  type = A3ObjectTypes.SpotLight;
  name = A3ObjectTypes.SpotLight;

  constructor( x, y, z ) {

    super( x, y, z );

    const spotLight = new SpotLight( this.color, this.intensity );
    spotLight.angle = Math.PI / 6;
    spotLight.penumbra = 0.1;
    spotLight.decay = this.decay;
    spotLight.distance = this.distance;

    spotLight.castShadow = true;
    spotLight.shadow.mapSize.width = 50;
    spotLight.shadow.mapSize.height = 50;
    spotLight.shadow.camera.near = 3;
    spotLight.shadow.camera.far = 50;
    spotLight.shadow.focus = .2;

    this.visual.visibel = false;
    this.threeObject.add( spotLight );
    this.threeObject.position.copy( this.position );

    this.lightHelper = new SpotLightHelper( spotLight );
    this.threeObject.add( this.lightHelper );

  }

}

class A3DirectionalLight extends A3Light {

  type = A3ObjectTypes.DirectionalLight;
  name = A3ObjectTypes.DirectionalLight;

  constructor( x, y, z ) {
    super( x, y, z );

    const light = new DirectionalLight( this.color, this.intensity );

    light.castShadow = true;
    const d = this.distance;
    light.shadow.camera.left = - d;
    light.shadow.camera.right = d;
    light.shadow.camera.top = d;
    light.shadow.camera.bottom = - d;

    light.shadow.camera.near = 2;
    light.shadow.camera.far = 50;

    light.shadow.mapSize.x = 1024;
    light.shadow.mapSize.y = 1024;

    this.threeObject.add( light );
    this.threeObject.position.copy( this.position );
    
  }
}
export { 
  A3PointLight,
  A3SpotLight,
  A3DirectionalLight,
};